
package com.scjyzr.mysweeper;

import android.app.AlertDialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import java.util.ArrayList;

public class GameView extends SurfaceView implements SurfaceHolder.Callback, MyCallBack {

    public GameView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        p = new Paint();
        sfh = this.getHolder();
        sfh.addCallback(this);

        this.setKeepScreenOn(true);
        setFocusable(true);

        Log.i("scj", "GameView");
    }

    public MyCallBack getMyParentCallBack() {
        return myParentCallBack;
    }

    public void setMyParentCallBack(MyCallBack myParentCallBack) {
        this.myParentCallBack = myParentCallBack;
    }

    public void restartGame() {
        clearOldData();

        int mineNumber = MyUtil.getCurrentMineNumber(context,heightCount*widthCount);
        if (business != null) {
            business.clear();
        }

        business = new Business(widthCount, heightCount, mineNumber);
        initializeView();

    }

    /**
     * 点击屏幕触发事件。
     * 
     * @param x
     * @param y
     * @return 当前点击是否有效
     */
    public boolean onClick(float x, float y, boolean isFlag, String currentTime) {
        int[] index = getPoints(x, y);
        if (isRightData(index[0], index[1])) {
            MyVibrator.getVibrator().IsVibrator(context);

            String value = index[0] + sign + index[1];
            // 表示是插旗
            if (isFlag) {

                // 插旗情况只能点击还没有点击的地方
                if (haveClickdata.contains(value)) {
                    return false;
                }

                StatisiticUtil.functiontSatistics(context, StatisiticUtil.StatisticKey.SELECT_FLAG);
                
                if (haveCheck.contains(value)) {
                    haveCheck.remove(value);
                    drawImage(index[0], index[1], true, true);
                } else {
                    haveCheck.add(value);
                    drawImage(index[0], index[1], true, false);
                }
                return true;
            }

            if (!haveClickdata.contains(value)) {

                if (Business.MINE_TAG == business.getCurrent(index[0], index[1])) {
                    // 表示碰到地理了
                    String message = String
                            .format(context.getString(R.string.is_bome), currentTime);
                    AlertDialog dia = MyUtil.showOkCancle(context, this, message,
                            MyCallBack.IS_GAME_OVER);
                    dia.show();

                } else {
                    // 自动展开功能
                    ArrayList<int[]> showPaint=new ArrayList<int[]>();
                    autoOpen(index[0], index[1],showPaint);
                    Log.i("scj", "1111111111111111 "+showPaint.size());
                        
                    
                    if(showPaint.size()>=0&&showPaint.size()<((heightCount*widthCount)/10))
                    {
                        for(int[] element:showPaint)
                        {
                            drawImage(element[0], element[1], false, false); 
                        }
                        if (!haveClickdata.contains(value)) {
                            haveClickdata.add(value);
                            drawImage(index[0], index[1], false, false);
                        }

                    }else
                    {
                        initializeView();
                    }
                    

                }
            }

        } else {
            return false;
        }
        // 如果扫雷赢利，提示用户，并且把所有数据展开.
        if (isWin()) {
            // 把所有的数据都展开

            int historyScore = MyUtil.getScore(context);
            int current = Integer.valueOf(currentTime);
            String message="";
            
            if(historyScore<=0)
            {
                message=String.format(context.getString(R.string.win0), currentTime);
                MyUtil.saveScore(current, context);
            }else if(historyScore>current)
            {
                message = String.format(context.getString(R.string.win1), currentTime,
                        (historyScore - current));
                MyUtil.saveScore(current, context);  
            }else
            {
                message = String.format(context.getString(R.string.win), currentTime,historyScore);
            }

            AlertDialog dia = MyUtil.showOkCancle(context, this, message, MyCallBack.IS_WIN);
            dia.show();
            if (myParentCallBack != null) {
                myParentCallBack.myCallBack(null, MyCallBack.IS_WIN);
            }
        }
        return true;
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        initializeVar();
        initializeView();
        Log.i("scj", "surfaceCreated");

    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        Log.i("scj", "surfaceChanged");
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        Log.i("scj", "surfaceDestroyed");

    }

    public void clearVar() {
        if (haveClickdata != null) {
            haveClickdata.clear();
            haveClickdata = null;
        }
        if (business != null) {
            business.clear();
        }

        if (haveCheck != null) {
            haveCheck.clear();
            haveCheck = null;
        }
        business = null;
        context = null;
        bitmap0 = null;
        bitmap1 = null;
        bitmap2 = null;
        bitmap3 = null;
        bitmap4 = null;
        bitmapBome = null;
        dst = null;
        sfh = null;
        canvas = null;
        p = null;
        myParentCallBack = null;
    }

    @Override
    public void myCallBack(Object object, int flag) {
        if (flag == MyCallBack.IS_WIN) {
            // 把这个数据全部填充haveClickdata
            if (business != null) {
                haveCheck.clear();
                int[][] alldata = business.getAllCurrent();
                if (alldata != null) {
                    haveClickdata.clear();
                    for (int x = 0; x < alldata.length; x++) {
                        for (int y = 0; y < alldata[x].length; y++) {
                            haveClickdata.add(x + sign + y);
                        }
                    }
                }
            }

        } else if (flag == MyCallBack.IS_GAME_OVER) {
            clearOldData();
            if (myParentCallBack != null) {
                myParentCallBack.myCallBack(null, MyCallBack.IS_GAME_OVER);
            }
        }
        initializeView();

    }

    private void clearOldData() {
        // 清除旧的数据
        haveClickdata.clear();
        haveCheck.clear();
    }

    // ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××//
    private void initializeVar() {
        if (heightCount > 0) {
            return;
        }

        // 有可能长框不是size的整数倍
        heightCount = (this.getHeight() - gap) / size;
        widthCount = (this.getWidth() - 2 * gap) / size;

        if (business == null) {
            int mineNumber = MyUtil.getCurrentMineNumber(context,heightCount*widthCount);
            business = new Business(widthCount, heightCount, mineNumber);
        }

        // 宽度的偏差量
        int reviseX = (this.getWidth() - widthCount * size - 2 * gap) / 2;
        // Y轴的修正变量，因为高度不一定是size的整数倍
        int reviseY = (this.getHeight() - heightCount * size - gap) / 2;
        // 绘制网格线的背景色
        p.setColor(Color.GRAY);

        beginx = gap + reviseX;
        beginy = reviseY;
        endx = widthCount * size + gap + reviseX;
        endy = heightCount * size + gap + reviseY;
    }

    /**
     * 初始化画布
     */
    private void initializeView() {
        canvas = sfh.lockCanvas();
        try {
            if (canvas != null) {
                canvas.drawColor(Color.GRAY);// 绘制背景颜色
                int[][] data = business.getAllCurrent();
                for (int x = 0; x < data.length; x++) {
                    for (int y = 0; y < data[x].length; y++) {
                        dst.set(x * size + beginx + lineWith, y * size + beginy + lineWith, (x + 1)
                                * size + beginx - lineWith, (y + 1) * size + beginy - lineWith);
                        if (haveClickdata.contains(x + sign + y)) {
                            canvas.drawBitmap(getBitmap(x, y, business.getCurrent(x, y), context),
                                    null, dst, p);

                        } else if (haveCheck.contains(x + sign + y)) {
                            canvas.drawBitmap(bitmapFlag, null, dst, p);
                        } else {
                            canvas.drawBitmap(bitmapbegin, null, dst, p);
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (canvas != null) {
                    sfh.unlockCanvasAndPost(canvas);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

    /**
     * 功能说明:指定区域绘制图片。
     * 
     * @param x
     * @param y
     * @param isFlag 是否是插旗操作
     * @param isBegin 是否是撤销插旗动作。
     * @date 2013-8-9
     * @author suchangjun
     * @since v1.0
     * @throws null
     */
    private void drawImage(int x, int y, boolean isFlag, boolean isBegin) {
        try {
            dst.set(x * size + beginx + lineWith, y * size + beginy + lineWith, (x + 1) * size
                    + beginx - lineWith, (y + 1) * size + beginy - lineWith);
            canvas = sfh.lockCanvas(dst);
            if (canvas != null) {
                if (isFlag) {
                    if (isBegin) {
                        canvas.drawBitmap(bitmapbegin, null, dst, p);
                    } else {
                        canvas.drawBitmap(bitmapFlag, null, dst, p);
                    }
                } else {

                    canvas.drawBitmap(getBitmap(x, y, business.getCurrent(x, y), context), null,
                            dst, p);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (canvas != null) {
                    sfh.unlockCanvasAndPost(canvas);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }

    }

    /**
     * 获取当前点击坐标的，左上角坐标。
     * 
     * @param x
     * @param y
     * @return
     */
    private int[] getPoints(float x, float y) {

        if ((x > beginx && x < endx) && (y > beginy && y < endy)) {
            float returnx = x / size;
            float returny = y / size;

            return new int[] {
                    (int) (returnx - 0.5), (int) (returny - 0.5)
            };
        }
        return new int[] {
                beginx, beginy
        };
    }

    /**
     * 根据地雷的数量获取对应的地雷。
     * 
     * @param x
     * @param y
     * @param number
     * @param context
     * @return
     */
    private Bitmap getBitmap(int x, int y, int number, Context context) {
        Bitmap bitmap = null;
        if (number == 0) {
            bitmap = bitmap0;

        } else if (number == Business.getMineTag()) {
            bitmap = bitmapBome;

        } else if (number == 1) {
            bitmap = bitmap1;

        } else if (number == 2) {
            bitmap = bitmap2;

        } else if (number == 3) {
            bitmap = bitmap3;

        } else if (number == 4) {
            bitmap = bitmap4;

        } else if (number == 5) {
            bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.five);

        } else if (number == 6) {
            bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.six);

        } else if (number == 7) {
            bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.seven);

        } else if (number == 8) {
            bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.eigth);

        }
        return bitmap;
    }

    /**
     * 功能说明:用来判断当前点击的点是否在范围内
     * 
     * @param x
     * @param y
     * @return
     * @date 2013-8-9
     * @author suchangjun
     * @since v1.0
     * @throws null
     */
    private boolean isRightData(int x, int y) {
        return (x >= 0 && x < widthCount) && (y >= 0 && y < heightCount);
    }

    private void autoOpen(int x, int y,ArrayList<int[]> showPaint) {
        Log.i("scj", "递归执行自定展开操作");
        
        if(showPaint.size()>=widthCount*heightCount)
        {
            return;
        }
        
        // 表示当前点击这个点是空白点
        if (business.getCurrent(x, y) == 0) {
            for (int i = -1; i <= 1; i++) {
                for (int j = -1; j <= 1; j++) {
                    // 去掉自己这个点
                    if (i != 0 || j != 0) {
                        if (isRightData(x + i, y + j)) {
                            if (!haveClickdata.contains((x + i) + sign + (y + j))) {
                                haveClickdata.add((x + i) + sign + (y + j));
//                                drawImage((x + i), (y + j), false, false);
                                showPaint.add(new int[]{(x + i), (y + j)});
                                autoOpen((x + i), (y + j),showPaint);

                            }
                        }

                    }
                }
            }

        }
    }

    /**
     * 判断是否已经全部把地雷扫完。
     * 
     * @return
     */
    private boolean isWin() {
        boolean result = false;
        // 已经发现的非地雷的数量
        int notMineNumber = haveClickdata.size();
        if (notMineNumber == business.getisNotMineSize()) {
            result = true;
        }
        return result;

    }

    private SurfaceHolder sfh;

    private Canvas canvas;

    private Paint p;

    private int gap = 20;

    private int size = 80;// 正方形的边长

    // 网格起点坐标
    private int beginx = 0;

    private int beginy = 0;

    private int heightCount = 0;

    private int widthCount = 0;

    // 网格终点坐标
    private int endx = 0;

    private int endy = 0;

    // 坐标线的宽度
    private int lineWith = 2;

    private String sign = ",";

    /**
     * 用来存储已经点击的坐标 x,y,1 x y代表坐标值，第三个-1 表示地雷，0表示没有地雷，数量表示旁边的地雷数量。
     */
    private ArrayList<String> haveClickdata = new ArrayList<String>();

    // 用来表示插旗的数据
    private ArrayList<String> haveCheck = new ArrayList<String>();

    private Business business = null;

    private Context context;

    private Bitmap bitmapbegin = BitmapFactory
            .decodeResource(this.getResources(), R.drawable.point);

    private Bitmap bitmap0 = BitmapFactory.decodeResource(this.getResources(), R.drawable.zeno);

    private Bitmap bitmap1 = BitmapFactory.decodeResource(this.getResources(), R.drawable.one);

    private Bitmap bitmap2 = BitmapFactory.decodeResource(this.getResources(), R.drawable.two);

    private Bitmap bitmap3 = BitmapFactory.decodeResource(this.getResources(), R.drawable.three);

    private Bitmap bitmap4 = BitmapFactory.decodeResource(this.getResources(), R.drawable.four);

    private Bitmap bitmapBome = BitmapFactory.decodeResource(this.getResources(), R.drawable.bomb);

    private Bitmap bitmapFlag = BitmapFactory.decodeResource(this.getResources(), R.drawable.flag);

    private Rect dst = new Rect();

    // 用来回调父容器的句柄。
    private MyCallBack myParentCallBack;

}
